//
// Created on 2025/1/10.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "Xcom.h"

namespace NativeModule {

OHNativeWindow *XcomNode::nativeWindow = nullptr;

XcomNode::XcomNode(float width, float height, std::string fileName)
    : ArkUINode((NativeModuleInstance::GetInstance()->GetNativeNodeAPI())->createNode(ARKUI_NODE_XCOMPONENT))
{
    ArkUI_NumberValue value[] = {};
//    ArkUI_AttributeItem item = {value, 1, "changeSize"};
    width_ = width * 3.25;
    height_ = height * 3.25;
    fileName_ = fileName;

    value[0].u32 = ARKUI_XCOMPONENT_TYPE_SURFACE;
    ArkUI_AttributeItem item = {value, 1, .string = "lalhan1"};
    nativeModule_->setAttribute(handle_, NODE_XCOMPONENT_TYPE, &item);
    nativeModule_->setAttribute(handle_, NODE_XCOMPONENT_ID, &item);

    value[0].u32 = width_;
    value[1].u32 = height_;
    item = {value};
    nativeModule_->setAttribute(handle_, NODE_XCOMPONENT_SURFACE_SIZE, &item);

    value[0].f32 = width;
    item = {value};
    nativeModule_->setAttribute(handle_, NODE_WIDTH, &item);
    value[0].f32 = height;
    item = {value};
    nativeModule_->setAttribute(handle_, NODE_HEIGHT, &item);

    auto *nativeXComponent = OH_NativeXComponent_GetNativeXComponent(handle_);

    if (!nativeXComponent) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginManager", "GetNativeXComponent error");
    }

    OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginManager", "创建成功 GetNativeXComponent success");

    callback_.OnSurfaceCreated = OnSurfaceCreated;
//    callback_.OnSurfaceChanged = OnSurfaceChanged;
//    callback_.OnSurfaceDestroyed = OnSurfaceDestroyed;
//    callback_.DispatchTouchEvent = DispatchTouchEvent;

    OH_NativeXComponent_RegisterCallback(nativeXComponent, &callback_);

    auto idRet = nativeModule_->getAttribute(handle_, NODE_XCOMPONENT_ID);
    OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "PluginManager", "xcomponent id: %{public}s", idRet->string);
}

void XcomNode::OnSurfaceCreated(OH_NativeXComponent *component, void *window)
{
    uint64_t width_;
    uint64_t height_;
    OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "PluginManager::OnSurfaceCreated");
    int32_t ret;
    char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {};
    uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
    ret = OH_NativeXComponent_GetXComponentId(component, idStr, &idSize);
    ret = OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_);
    OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native",
                 "实际的宽高为 ret=%{public}d width=%{public}lu, height=%{public}lu", ret, width_, height_);
    if (ret == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
        nativeWindow = static_cast<OHNativeWindow *>(window);
//        PrepareSurface();
    }
}

void XcomNode::PrepareSurface()
{
    int32_t usage = NATIVEBUFFER_USAGE_CPU_READ | NATIVEBUFFER_USAGE_CPU_WRITE | NATIVEBUFFER_USAGE_MEM_DMA;
    int ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_USAGE, usage);
    if (ret != 0) {
        DRAWING_LOGE("failed to OH_NativeWindow_NativeWindowHandleOpt");
        return;
    }
    // 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 OHNativeWindowBuffer 实例
    ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &buffer_, &fenceFd_);
    DRAWING_LOGE("request buffer ret = %{public}d", ret);
    // 通过 OH_NativeWindow_GetBufferHandleFromNative 获取 buffer 的 handle
    bufferHandle_ = OH_NativeWindow_GetBufferHandleFromNative(buffer_);
    mappedAddr_ = static_cast<uint32_t *>(
        mmap(bufferHandle_->virAddr, bufferHandle_->size, PROT_READ | PROT_WRITE, MAP_SHARED, bufferHandle_->fd, 0));
    if (mappedAddr_ == MAP_FAILED) {
        DRAWING_LOGE("mmap failed");
    }
}




}